(function() {
	var panel;
	var context;
	var isDraw = false; //线条连线是否开启
	//初始化流程设计器
	WorkFlow = function(edit, approve) {
		//1、创建Raphael画板对象
		panel = Raphael("paper", 1100, 600);
		context = new TaskContext();
		context.edit = edit; //是否可以编辑
		//isDraw = approve; //是否可以修改审批人
		
		toolInit();
		btnEvent();
	};
	//------------------------------------Map----begin--------------------------------
	/**
	 * js Map对象  workFlow对象管理器
	 * 管理taskArea和Link对象
	 * 说明：每创建一个新的taskArea对象，该对象都会被注册到此map中。每创建一个Line对象，该对象都会被注册到TaskArea对象中。
	 * 功能：
	 * 1、提供taskArea和Line对象的托管
	 * 2、管理TaskArea和Line的创建器
	 * 3、提供DataLine接口，为taskArea和line业务数据的修改和传输
	 * 4、提供workFlow数据保存的数据封装功能，包括数据整理保存，数据上传加载，数据下载加载功能
	 * 
	 * 管理器托管TaskArea创建器对象和Line创建器对象。
	 */
	function TaskContext() {
		this.map_key = []; //定义key
		this.cid = 224; //任务自动生成id
		
		this.graphId = 0; //数据库Id
		this.name = ""; //流程名称
		this.proClass = ""; //执行Java类
		this.folderId = 0; //文件夹Id
		this.appRole = ""; //发起人角色
		
		this.edit = true; //是否可以编辑
		
		//当前获得操作权的Line或者TaskArea对象：删除时使用
		this.isMe;
		
		//是否已被编辑--保留功能-未实现
		var isEdit = false;
		
		//托管line模板对象
		this.lt = new LineTemp();
		//托管Task模板对象
		new TaskTemp();
		new TaskBegin();
		new TaskEnd();
		
		/**设置context流程图信息
		 * 加载流程图时调用
		 */
		TaskContext.prototype.setData = function(o) {
			if(o["graphId"] != undefined) {
				this.graphId = o["graphId"];
			}
			if(o["name"] != undefined) {
				this.name = o["name"];
			}
			if(o["proClass"] != undefined) {
				this.proClass = o["proClass"];
			}
			if(o["folderId"] != undefined) {
				this.folderId = o["folderId"];
			}
			if(o["appRole"] != undefined) {
				this.appRole = o["appRole"];
			}
		};
		
		/**map数据总数
		 */
		TaskContext.prototype.getId = function(i) {
			if(i != undefined) {
				this.cid = i;
			}
			return this.cid++;
		};
		
		/**task光圈点击事件--添加该点至线条模板
		 */
		TaskContext.prototype.addLinePoint = function(tid, point) {
			this.lt.addPoint(tid, point);
		};
		
		/**添加连线时task光圈的hover显示方法
		 */
		TaskContext.prototype.linkHover = function() {
			this.forEach(function(k, v) {
				if(v.flag != 2) {
					v.task.items[1].show();
				}
			});
		};
		
		/**添加连线时task光圈的hover显示方法
		 */
		TaskContext.prototype.linkUnhover = function(tid) {
			if(tid != undefined) { //线条确定的一个点
				this.get(tid).task.items[1].hide();
				// 打开taskEnd感应圈并关闭taskBegin感应圈
				this.forEach(function(k, v) {
					if(v.flag == 2) {
						v.task.items[1].show();
					}else if(v.flag == 1) {
						v.task.items[1].hide();
					}
				});
			}else {
				this.forEach(function(k, v) {
					v.task.items[1].hide();
				});
			}
		};
		
		/**添加连线时task光圈的hover显示方法
		 */
		TaskContext.prototype.dataPanel = function(o) {
			dataLink(o);
		};
		
		/**格式化workFlow数据，为发布流程和保存流程提供数据
		 */
		TaskContext.prototype.fmtGraph = function() {
			return "{graphId:"+this.graphId+",name:'"+this.name+"',proClass:'"+this.proClass+"',folderId:"+this.folderId+",appRole:'"+this.appRole+"'}";
		};
		/**格式化workFlow数据，为发布流程和保存流程提供数据
		 */
		TaskContext.prototype.fmtTask = function() {
			var tasks = [];
			this.forEach(function(k, v) {
				tasks.push(v.fmtDate());
			});
			
			return "["+tasks.join(",")+"]";
		};
		/**格式化workFlow数据，为发布流程和保存流程提供数据
		 */
		TaskContext.prototype.fmtLine = function() {
			var lines = [];
			this.forEach(function(k, v) {
				for (var i=0; i < v.myLine.length; i++) {
				  lines.push(v.myLine[i].fmtDate());
				};
			});
			
			return "["+lines.join(",")+"]";
		};
		
		/**根据流程图数据，建立流程图像
		 */
		TaskContext.prototype.initDate = function(o) {
			//初始化context
			this.setData(o);
			//初始化taskArea
			//{"id":2,"graphId":1,"tid":225,"x":0,"y":0,"text":"任务说明","tx":0,"ty":0,"step":0,"flag":2}
			var tas = o.tasks;
			for(var i=0; i<tas.length; i++) {
				if(tas[i].flag == 1) { //begin
					TaskAreaBegin.prototype = new TaskArea(tas[i]);
					var t = new TaskAreaBegin();
					t.init(t);
				}else if(tas[i].flag == 2) { //end
					TaskAreaEnd.prototype = new TaskArea(tas[i]);
					var t = new TaskAreaEnd();
					t.init(t);
				}else {
					var t = new TaskArea(tas[i]);
					t.init(t);
				}
			}
			//初始化Line
			//{"id":1,"graphId":1,"lid":227,"tid":224,"growTo":225,"text":"转向","tx":0,"ty":0,"points":"[{cx:399,cy:86},{cx:399,cy:178}]"}
			var ls = o.lines;
			for(var i=0; i<ls.length; i++) {
				new Line(ls[i]);
			}
			//查看模式下高亮显示TaskArea
			if(o.highLight != undefined) {
				this.get(highLight).task.items[0].attr({
					"stroke": "red",
					"stroke-width": 4
				});
			}
		};
		/**根据流程图数据，建立流程图像
		 */
		TaskContext.prototype.reset = function() {
			$("#paper").empty();
			//重置面板
			panel = Raphael("paper", 1100, 600);
			context = new TaskContext();
		};
		/**$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$
		 * map数据总数
		 */
		TaskContext.prototype.size = function() {
			return this.map_key.length;
		};
		
		/**添加数据方法
		 */
		TaskContext.prototype.put = function(key, value) {
			this.map_key.push(key);
			this[key] = value;
		};
		
		/**删除数据方法
		 */
		TaskContext.prototype.remove = function(key) {
			//删除Array中对应的元素
			for (var i = 0; i < this.map_key.length; i++) {
			  if(key == this.map_key[i]) {
			  	this.map_key.splice(i, 1);
			  	break;
			  }
			};
			
			this[key].destroy();
			delete this[key];
		};
		
		/**获得数据方法
		 */
		TaskContext.prototype.get = function(key) {
			return this[key];
		};
		
		/**map迭代器
		 */
		TaskContext.prototype.forEach = function(fn) {
			if(typeof fn != "function") {
				return;
			}
			for(var i = 0; i < this.map_key.length; i++) {
			  fn(this.map_key[i], this[this.map_key[i]]);
			}
		};
	};
	//------------------------------------Map-----end----------------------------------
	
	//------------------------------------TaskArea----begin--------------------------------
	/**
	 * 任务对象
	 * 任务对象提供任务的图形创建及图形动画效果、任务数据初始化及数据管理工作。
	 * 任务对象托管Line对象，包括指向自己的line和从此任务出发，指向别的任务的line。
	 * 任务对象提供销毁自身的方法。包括销毁指向自己的line和从此任务出发，指向别的任务的line。
	 * 任务对象托管任务说明文字对象
	 */
	
	//设置任务线圈属性
	Raphael.el.Linker = function(tid) {
		this.attr({
			fill: "#005AB5",
			"fill-opacity": 0.1,
			"stroke-opacity": 0.1,
			cursor: "hand"
		}).hide();
		this.click(function(e) {
			context.addLinePoint(tid, this);
			stop(e);
		});
		return this;
	};
	
	/**流程任务对象
	 */
	function TaskArea(opt) {
		this.id = opt["id"]; //数据库主键
		this.step = opt["step"]; //流程任务步骤
		this.x = opt["x"]; //图标x坐标
		this.y = opt["y"]; //图标y坐标
		this.text = opt["text"]; //task说明文本
		this.appRole = opt["appRole"];//当前办理审批角色
		this.page = opt["page"]; //任务对应页面
		this.toLine = []; //指向此task的线条
		this.myLine = []; //task对象指向其他task的线条
		this.tid;//任务图标唯一标识
		
		if(opt["tid"] != undefined) {
			this.tid = context.getId(opt["tid"]);
		}else {
			this.tid = context.getId();
		}
	};
	//TaskArea公有化方法-------------begin-------------------
	/**任务对象初始化  {taskId:3329,step:1,x:23,y74,text:'hey'}
	 */
	TaskArea.prototype.init = function(o) {
		o.task = panel.set(); //任务对象
		o.flag = 0;
		//创建task图像
		o.task.push(
			panel.rect(o.x, o.y, 100, 50).attr({
				fill: "#AAA",
				"fill-opacity": 0.4
			}),
			panel.set().push(
				panel.circle(o.x+30, o.y, 5).Linker(o.tid),
				panel.circle(o.x+50, o.y, 5).Linker(o.tid),
				panel.circle(o.x+70, o.y, 5).Linker(o.tid),
				panel.circle(o.x+100, o.y+15, 5).Linker(o.tid),
				panel.circle(o.x+100, o.y+35, 5).Linker(o.tid),
				panel.circle(o.x+70, o.y+50, 5).Linker(o.tid),
				panel.circle(o.x+50, o.y+50, 5).Linker(o.tid),
				panel.circle(o.x+30, o.y+50, 5).Linker(o.tid),
				panel.circle(o.x, o.y+15, 5).Linker(o.tid),
				panel.circle(o.x, o.y+35, 5).Linker(o.tid)
			)
		);
		//任务图像拖拽方法
		var t = o.task.items[0];
		t.drag(function(offset_x, offset_y) { //move
			if(!isDraw) { //连线时，禁止图标移动
				o.move(offset_x, offset_y);
			}
		}, function() { //begin
			//自定义属性：获取矩阵坐标
			t.data("pos", t.attr(["x", "y"]));
			o.text.data("pos", o.text.attr(["x", "y"]));
			//注册当前操作的task对象
			o.isMe(true);
			//阻止事件冒泡
			stop(arguments[2]);
		});
		//创建task说明文本
		o.text = panel.text(o.x+35, o.y+20, o.text).attr({
			"cursor": "move",//移动
			"font-size":16
		}).drag(function(offset_x, offset_y) { //move
			var pos = this.data("pos");
			this.attr({
				cursor: "move",//移动
				x: pos.x + offset_x,
				y: pos.y + offset_y
			});
		}, function() { //begin
			this.data("pos", o.text.attr(["x", "y"]));
		});
		//2、将任务的引用放入TaskContext中
		context.put(o.tid, o);
		//注册当前操作的task对象
		o.isMe(true);
	}
	/**Line对象获得焦点事的事件
	 */
	TaskArea.prototype.isMe = function(f) {
		if(f) {//获得焦点
			if(context.isMe) {
				context.isMe.isMe(false);//取消之前的焦点元素
			}
			//注册当前操作的TaskArea对象到context
			context.isMe = this;
			this.text.attr("fill", "red");
			//数据面板数据同步
			context.dataPanel({
				text: this.text.attr("text"),
				step: this.step,
				appRole: this.appRole,
				page: this.page
			});
		}else {
			context.isMe = null;
			this.text.attr("fill", "black");
		}
	};
	/**添加Line对象
	 */
	TaskArea.prototype.addLine = function(line) {
		this.toLine.push(line);
	};
	/**销毁taskArea对象
	 */
	TaskArea.prototype.destroy = function() {
		this.task.remove();
		this.text.remove();
		//线条销毁
		while(this.myLine.length > 0) {
			this.myLine[0].destroy();
		}
		//线条销毁
		while(this.toLine.length > 0) {
			this.toLine[0].destroy();
		}
		
		context.isMe = null;
	};
	
	/**格式化TaskArea数据，为发布流程和保存流程提供数据
	 */
	TaskArea.prototype.fmtDate = function() {
		var s = "{";
		if(this.id != undefined) {
			s += "id:"+this.id+",";
		}
		s += "tid:"+this.tid+",text:'"+this.text.attr("text")+"',tx:"+this.text.attr("x")+",ty:"+this.text.attr("y");
		if(this.step != undefined) {
			s += ",step:"+this.step;
		}
		if(this.appRole != undefined) {
			s += ",appRole:'"+this.appRole+"'";
		}
		if(this.page != undefined) {
			s += ",page:'"+this.page+"'";
		}
		if(this.flag == 1 || this.flag == 2) {
			return s + ",x:"+this.task.items[0].attr("cx")+",y:"+this.task.items[0].attr("cy")+",flag:"+this.flag+"}";
		}
		return s + ",x:"+this.task.items[0].attr("x")+",y:"+this.task.items[0].attr("y")+",flag:"+this.flag+"}";
	};
	/**任务移动方法
	 */
	TaskArea.prototype.move = function(x, y) {
		var pos = this.task.items[0].data("pos");
		var tpos = this.text.data("pos");
		var circles = this.task.items[1];
		//1、移动自身
		this.task.items[0].attr({
			x: pos.x + x,
			y: pos.y + y
		});
		circles.items[0].attr({cx:pos.x+30+x, cy:pos.y+y});
		circles.items[1].attr({cx:pos.x+50+x, cy:pos.y+y});
		circles.items[2].attr({cx:pos.x+70+x, cy:pos.y+y});
		circles.items[3].attr({cx:pos.x+100+x, cy:pos.y+15+y});
		circles.items[4].attr({cx:pos.x+100+x, cy:pos.y+35+y});
		circles.items[5].attr({cx:pos.x+70+x, cy:pos.y+50+y});
		circles.items[6].attr({cx:pos.x+50+x, cy:pos.y+50+y});
		circles.items[7].attr({cx:pos.x+30+x, cy:pos.y+50+y});
		circles.items[8].attr({cx:pos.x+x, cy:pos.y+15+y});
		circles.items[9].attr({cx:pos.x+x, cy:pos.y+35+y});
		//2、移动text
		this.text.attr({
			x: tpos.x + x,
			y: tpos.y + y
		});
		//3、移动myLine
		for(var i = 0; i < this.myLine.length; i++) {
			this.myLine[i].moveFirst();
		}
		//4、移动toLine
		for(var i = 0; i < this.toLine.length; i++) {
			this.toLine[i].moveLast();
		}
	};
	//TaskArea公有化方法-------------end-------------------
	//TaskArea开始对象--------------------begin----------------------
	/**流程任务开始对象
	 */
	function TaskAreaBegin() {
		/**
		 * 初始化
		 */
		this.init = function(o) {
			o.task = panel.set(); //任务对象
			o.flag = 1;
			//创建task图像
			o.task.push(
				panel.circle(o.x, o.y, 23).attr({
					fill: "#7fffd4",
					"fill-opacity": 0.6,
					"stroke-opacity": 0.2,
					"stroke-width": 10
				}),
				panel.set().push(
					panel.circle(o.x, o.y-28, 5).Linker(o.tid),
					panel.circle(o.x+28, o.y, 5).Linker(o.tid),
					panel.circle(o.x, o.y+28, 5).Linker(o.tid),
					panel.circle(o.x-28, o.y, 5).Linker(o.tid)
				)
			);
			//任务图像拖拽方法
			var t = o.task.items[0];
			t.drag(function(offset_x, offset_y) { //move
				if(!isDraw) { //连线时，禁止图标移动
					o.move(offset_x, offset_y);
				}
			}, function() { //begin
				//自定义属性：获取矩阵坐标
				t.data("pos", t.attr(["cx", "cy"]));
				o.text.data("pos", o.text.attr(["x", "y"]));
				//注册当前操作的task对象
				o.isMe(true);
				//阻止事件冒泡
				stop(arguments[2]);
			});
			//创建task说明文本
			o.text = panel.text(o.x+50, o.y, "开始").attr({
				"cursor": "move",//移动
				"font-size":16
			}).drag(function(offset_x, offset_y) { //move
				var pos = this.data("pos");
				this.attr({
					cursor: "move",//移动
					x: pos.x + offset_x,
					y: pos.y + offset_y
				});
			}, function() { //begin
				this.data("pos", o.text.attr(["x", "y"]));
			});
			
			//2、将任务的引用放入TaskContext中
			context.put(o.tid, o);
			//注册当前操作的task对象
			o.isMe(true);
		};
		
		/**任务移动方法
		 */
		this.move = function(x, y) {
			var pos = this.task.items[0].data("pos");
			var tpos = this.text.data("pos");
			var circles = this.task.items[1];
			//1、移动自身
			this.task.items[0].attr({
				cx: pos.cx + x,
				cy: pos.cy + y
			});
			circles.items[0].attr({cx:pos.cx+x, cy:pos.cy-28+y});
			circles.items[1].attr({cx:pos.cx+28+x, cy:pos.cy+y});
			circles.items[2].attr({cx:pos.cx+x, cy:pos.cy+28+y});
			circles.items[3].attr({cx:pos.cx-28+x, cy:pos.cy+y});
			//2、移动text
			this.text.attr({
				x: tpos.x + x,
				y: tpos.y + y
			});
			//3、移动myLine
			for(var i = 0; i < this.myLine.length; i++) {
				this.myLine[i].moveFirst();
			}
		};
	};
	//TaskArea开始对象--------------------end----------------------
	//TaskArea结束对象--------------------begin----------------------
	/**流程任务结束对象
	 */
	function TaskAreaEnd() {
		/**
		 * 初始化
		 */
		this.init = function(o) {
			o.task = panel.set(); //任务对象
			o.flag = 2;
			//创建task图像
			o.task.push(
				panel.circle(o.x, o.y, 23).attr({
					fill: "#FF4040",
					"fill-opacity": 0.6,
					"stroke-opacity": 0.2,
					"stroke-width": 10
				}),
				panel.set().push(
					panel.circle(o.x, o.y-28, 5).Linker(o.tid),
					panel.circle(o.x+28, o.y, 5).Linker(o.tid),
					panel.circle(o.x, o.y+28, 5).Linker(o.tid),
					panel.circle(o.x-28, o.y, 5).Linker(o.tid)
				)
			);
			//任务图像拖拽方法
			var t = o.task.items[0];
			t.drag(function(offset_x, offset_y) { //move
				if(!isDraw) { //连线时，禁止图标移动
					o.move(offset_x, offset_y);
				}
			}, function() { //begin
				//自定义属性：获取矩阵坐标
				t.data("pos", t.attr(["cx", "cy"]));
				o.text.data("pos", o.text.attr(["x", "y"]));
				//注册当前操作的task对象
				o.isMe(true);
				//阻止事件冒泡
				stop(arguments[2]);
			});
			//创建task说明文本
			o.text = panel.text(o.x+50, o.y, "结束").attr({
				"cursor": "move",//移动
				"font-size":16
			}).drag(function(offset_x, offset_y) { //move
				var pos = this.data("pos");
				this.attr({
					cursor: "move",//移动
					x: pos.x + offset_x,
					y: pos.y + offset_y
				});
			}, function() { //begin
				this.data("pos", o.text.attr(["x", "y"]));
			});
			
			//2、将任务的引用放入TaskContext中
			context.put(o.tid, o);
			//注册当前操作的task对象
			o.isMe(true);
		};
		
		/**任务移动方法
		 */
		this.move = function(x, y) {
			var pos = this.task.items[0].data("pos");
			var tpos = this.text.data("pos");
			var circles = this.task.items[1];
			//1、移动自身
			this.task.items[0].attr({
				cx: pos.cx + x,
				cy: pos.cy + y
			});
			circles.items[0].attr({cx:pos.cx+x, cy:pos.cy-28+y});
			circles.items[1].attr({cx:pos.cx+28+x, cy:pos.cy+y});
			circles.items[2].attr({cx:pos.cx+x, cy:pos.cy+28+y});
			circles.items[3].attr({cx:pos.cx-28+x, cy:pos.cy+y});
			//2、移动text
			this.text.attr({
				x: tpos.x + x,
				y: tpos.y + y
			});
			//3、移动toLine
			for(var i = 0; i < this.toLine.length; i++) {
				this.toLine[i].moveLast();
			}
		};
	};
	//TaskArea结束对象--------------------end----------------------
	//------------------------------------TaskArea----end------------------------------
	
	//------------------------------------Line----begin--------------------------------
	/**流程线条对象
	 * line对象是任务图标之间的连接器、指明任务下一办理的路径。
	 * line对象被TaskArea对象托管
	 * 功能：
	 * 1、提供line对象的数据初始化、line对象的图形创建、line对象的数据加载及数据整理
	 * 2、提供line对象销毁自身的方法。
	 * 3、提供line对象的动画效果。
	 * 
	 * line对象托管line的文字说明对象
	 */
	function Line(opt) {
		this.id = opt["id"];//数据库唯一标识
		this.points = [];
		this.line;//线条图形
		this.path;//线条路径--线条移动时使用
		this.text = opt["text"];//文字说明图形
		this.tid = opt["tid"]; //属于哪一个task
		this.growTo = opt["growTo"]; //指向task的id
		this.text = opt["text"]; //线条说明文字
		this.exeCid = opt["exeCid"]; //执行条件
		this.lid; //线条Id 唯一标识符
		
		if(opt["lid"] != undefined) {
			this.lid = context.getId(opt["lid"]);
			
		}else {
			this.lid = context.getId();
		}
		
		/**线条初始化 {growTo:2346, points:[{cx:20,cy:45},{cx:20,cy:45}, text:'key']}
		 */
		this.init(this, opt);
		
	};
	//Line公有化方法-------------begin---------------------
	Line.prototype.init = function(o, opt) {
		//创建线条对象
		o.line = panel.path().attr({
		  "arrow-end": "block-wide-long",
		  "stroke": "#585858",
		  "stroke-width": 1.5
		});
		//线条点定位及布局
		var ps = opt.points;
		if(typeof s != "object") {
			ps = eval(opt.points);
		}
		//起始点
		context.get(opt.tid).task.items[1].forEach(function(c) {
			if(ps[0].cx == c.attr("cx") && ps[0].cy == c.attr("cy")) {
				o.points.push(c);
			}
		});
		//中间点
		if(ps.length > 2) {
			for(var i = 1; i < ps.length-1; i++) {
				//创建线条节点对象
				var point = panel.circle(ps[i].cx, ps[i].cy, 5);
				point.data("index", i); //设置点集在数组中下标位置
				//设置线条节点属性
				point.attr({
					"fill": "red",
					"opacity": 0.2,
					cursor: "move"
				}).hide();
				o.points.push(point);
				//拖拽
				point.drag(function(offset_x, offset_y) { //move
					o.move(this, offset_x, offset_y);
				}, function() { //begin
					//自定义属性：圆心坐标
					this.data("pos", this.attr(["cx", "cy"]));
					//绘制线条路径模板
					var arr = o.line.attr("path").toString().split("L");
					arr[this.data("index")] = "$";
					o.path = arr.join("L");
				});
			}
		}
		//结束点
		a = ps[ps.length-1];
		context.get(opt.growTo).task.items[1].forEach(function(c) {
			if(a.cx == c.attr("cx") && a.cy == c.attr("cy")) {
				o.points.push(c);
			}
		});
		//绘制线条path
		var path = "M" + o.getPos(o.points[0]);
		for(var i = 1; i < o.points.length; i++) {
			path += "L" + o.getPos(o.points[i]);
		}
		o.line.attr("path", path);
		//线条说明文字
		var tx, ty;
		if(opt.tx != undefined && opt.ty != undefined) {
			tx = opt.tx;
			ty = opt.ty;
		}else {
			tx = Math.round((ps[0].cx + ps[1].cx)/2);
			ty = Math.round((ps[0].cy + ps[1].cy)/2);
		}
		o.text = panel.text(tx, ty, o.text).attr({
			"cursor": "move",//移动
			"font-size": 16
		}).drag(function(offset_x, offset_y) { //move
			var pos = this.data("pos");
			this.attr({
				x: pos.x + offset_x,
				y: pos.y + offset_y
			});
		}, function() { //begin
			this.data("pos", this.attr(["x", "y"]));
			//注册当前操作的line对象
			o.isMe(true);
		});
		
		//将线条的引用放入growTo对象的Task对象的myLine中
		context.get(opt.tid).myLine.push(o);
		context.get(opt.growTo).toLine.push(o);
		//注册当前操作的line对象
		o.isMe(true);
	};
	
	/**point移动时改变point的坐标并改变线条的形状
	 */
	Line.prototype.move = function(point, offset_x, offset_y) {
		var pos = point.data("pos");
		point.attr({
			cx: pos.cx + offset_x,
			cy: pos.cy + offset_y
		});
		//连线
		this.line.attr("path", this.path.replace("$", this.getPos(point)));
	};

	/**将Raphael的圆对象的圆心以cx，cy字符形式导出
	 */
	Line.prototype.getPos =  function(p) {
		return p.attr("cx") + "," + p.attr("cy");
	};
	
	/**Line对象获得焦点事的事件
	 */
	Line.prototype.isMe = function(f) {
		if(f) {
			if(context.isMe) {
				context.isMe.isMe(false);
			}
			//注册当前操作的line对象到context
			context.isMe = this;
			//显示线条的points
			for(var i=1; i < this.points.length-1; i++) {
				this.points[i].show();
			};
			this.text.attr("fill", "red");
			//数据面板数据同步
			context.dataPanel({
				text: this.text.attr("text"),
				exeCid: this.exeCid
			});
		}else {
			context.isMe = null;
			//隐藏线条的points
			for(var i=1; i < this.points.length-1; i++) {
				this.points[i].hide();
			};
			this.text.attr("fill", "black");
		}
	};
	
	/**point移动第一个点时改变point的坐标并改变线条的形状
	 */
	Line.prototype.moveFirst = function() {
		var path = this.line.attr("path").toString();
		path = path.substring(path.indexOf("L"), path.length);
		
		this.line.attr("path", "M"+this.getPos(this.points[0])+path);
	};
	/**point移动最后一个点时改变point的坐标并改变线条的形状
	 */
	 Line.prototype.moveLast = function() {
		var path = this.line.attr("path").toString();
		path = path.substring(0, path.lastIndexOf("L"));
		
		this.line.attr("path", path + "L" + this.getPos(this.points[this.points.length-1]));
	};
	/**销毁task对象
	 */
	Line.prototype.destroy = function() {
		this.line.remove();
		this.text.remove();
		//线条连线点
		for(var i=1; i < this.points.length-1; i++) {
			this.points[i].remove();
		};
		//删除task.toLine对该线条的引用
		var at = context.get(this.growTo).toLine;
		for(var i=0; i < at.length; i++) {
			if(at[i].lid == this.lid) {
				at.splice(i, 1);
				break;
			}
		};
		//删除此线条所属的task.myLine对该线条的引用
		var am = context.get(this.tid).myLine;
		for(var i=0; i < am.length; i++) {
			if(am[i].lid == this.lid) {
				am.splice(i, 1);
				break;
			}
		};
		
		context.isMe = null;
	};
	/**格式化Line数据，为发布流程和保存流程提供数据
	 */
	Line.prototype.fmtDate = function() {
		var o = "{";
		if(this.id != undefined) {
			o += "id:"+this.id+",";
		}
		o += "lid:"+this.lid+",tid:"+this.tid+",growTo:"+this.growTo+",text:'"+this.text.attr("text")+"',tx:"+this.text.attr("x")+",ty:"+this.text.attr("y");
		if(this.exeCid != undefined) {
			o += ",exeCid:'"+this.exeCid+"'";
		}
		var ps = [];
		for (var i=0; i < this.points.length; i++) {
			ps.push("{cx:"+this.points[i].attr("cx")+",cy:"+this.points[i].attr("cy")+"}");
		};
		return o + ",points:'[" + ps.join(",") + "]'}";
	};
	//Line公有化方法-------------end-------------------
	//------------------------------------Line-----end-------------------------------
	
	//-------------------------------------------task模板----begin----------------------------------------------
	/**
	 * 任务对象图形创建器
	 * 任务图形创建器是一个独立的图形，当其被激活要求创建TaskArea对象时，它会创建新的TaskArea对象，并提供初始化数据。
	 * 任务图形创建器对象提供自身的动画效果。
	 * 任务图形创建器又TaskContext对象托管
	 */
	function TaskTemp() {
		//taskArea底部样式模板
		var bg = panel.rect(50, 124, 40, 20).attr({
			fill: "#333",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.2
		});
		bg.hide();
		var temp = panel.rect(50, 124, 40, 20).attr({
			fill: "#333",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.2
		});
		
		var px, py;
		temp.drag(function(offset_x, offset_y) { //move
			//1、移动自身
			this.attr({
				x: px + offset_x,
				y: py + offset_y
			});
		}, function() { //begin
			//自定义属性：获取矩阵坐标
			px = this.attr("x");
			py = this.attr("y");
			bg.show();
		}, function() { //end
			if(this.attr("x") > 100 && this.attr("x") < 1000 && this.attr("y") > 10 && this.attr("y") < 600) {
				temp.animate({
					x:temp.attr("x")-30,
					y:temp.attr("y")-15,
					width:100,
					height:50
				}, 300, function() { //动画结束
					var t = new TaskArea({
						x: temp.attr("x"),
						y: temp.attr("y"),
						text: "任务说明"
					});
					t.init(t);
					reset();
				});
			}else {
				reset();
			}
		});
		
		//重置
		function reset() {
			temp.attr({
				x:50,
				y:124,
				width:40,
				height:20
			});
			bg.hide();
		};
	};
	
	/**
	 * 开始任务对象图形创建器
	 * 开始任务图形创建器又TaskContext对象托管
	 */
	function TaskBegin() {
		//taskArea底部样式模板
		var bg = panel.circle(70, 58, 12).attr({
			fill: "#7fffd4",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.2
		});
		bg.hide();
		var temp = panel.circle(70, 58, 12).attr({
			fill: "#7fffd4",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.3
		});
		
		var px, py;
		temp.drag(function(offset_x, offset_y) { //move
			//1、移动自身
			this.attr({
				cx: px + offset_x,
				cy: py + offset_y
			});
		}, function() { //begin
			//自定义属性：获取矩阵坐标
			px = this.attr("cx");
			py = this.attr("cy");
			bg.show();
		}, function() { //end
			if(this.attr("cx") > 100 && this.attr("cx") < 1000 && this.attr("cy") > 10 && this.attr("cy") < 600) {
				temp.animate({
					r: 25,
					"stroke-width": 10
				}, 300, function() { //动画结束
					//继承TaskArea
					TaskAreaBegin.prototype = new TaskArea({
						x: temp.attr("cx"),
						y: temp.attr("cy"),
						text: "开始"
					});
					var t = new TaskAreaBegin();
					t.init(t);
					reset();
				});
			}else {
				reset();
			}
		});
		
		//重置
		function reset() {
			temp.attr({
				cx: 70,
				cy: 58,
				r: 12,
				"stroke-width": 1
			});
			bg.hide();
		};
	};
	
	/**
	 * 开始任务对象图形创建器
	 * 开始任务图形创建器又TaskContext对象托管
	 */
	function TaskEnd() {
		//taskArea底部样式模板
		var bg = panel.circle(70, 96, 12).attr({
			fill: "#FF4040",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.2
		});
		bg.hide();
		var temp = panel.circle(70, 96, 12).attr({
			fill: "#FF4040",
			"fill-opacity": 0.6,
			"stroke-opacity": 0.3
		});
		
		var px, py;
		temp.drag(function(offset_x, offset_y) { //move
			//1、移动自身
			this.attr({
				cx: px + offset_x,
				cy: py + offset_y
			});
		}, function() { //begin
			//自定义属性：获取矩阵坐标
			px = this.attr("cx");
			py = this.attr("cy");
			bg.show();
		}, function() { //end
			if(this.attr("cx") > 100 && this.attr("cx") < 1000 && this.attr("cy") > 10 && this.attr("cy") < 600) {
				temp.animate({
					r: 25,
					"stroke-width": 10
				}, 300, function() { //动画结束
					//继承TaskArea
					TaskAreaEnd.prototype = new TaskArea({
						x: temp.attr("cx"),
						y: temp.attr("cy"),
						text: "结束"
					});
					var t = new TaskAreaEnd();
					t.init(t);
					reset();
				});
			}else {
				reset();
			}
		});
		
		//重置
		function reset() {
			temp.attr({
				cx: 70,
				cy: 96,
				r: 12,
				"stroke-width": 1
			});
			bg.hide();
		};
	};
	//-------------------------------------------task模板----end----------------------------------------------
	
	//----------------------JQuery注入---------------------line模板----begin------------------------------------
	/**
	 * line图形创建器
	 * line图形创建器对象是一个独立的图形，当期激活时，点击连接两个任务图形时，会创建一个Line对象。自身则销毁。
	 * line图形创建对象提供自身的动画效果
	 * line图形创建器有TaskContext对象托管
	 * line对象部分功能有JQuery完成
	 */
	function LineTemp() {
		var newPath; //线条模板的路径
		var opt = {tid:0, growTo:0, points:[], text:"转向"};
		
		var ts = this;
		var newLine = panel.path().attr({
		  "arrow-end": "block-wide-long",
		  "stroke": "#585858",
		  "stroke-width": 1.5
		});
		
		/**创建连线图标并开启线条连线感应框
		 */
		panel.path("M50,171L90,171").attr({
			"arrow-end": "block-wide-long",
			"stroke-width": 1.5
		});
		panel.rect(50, 161, 40, 20).attr({
			fill: "#333",
			"fill-opacity": 0.2,
			"stroke-opacity": 0.2
		}).click(function(e) { //连线开启方法
			//1、画笔初始化
			var x, y;
			$("#cloth").show();//打开遮布，防止点击工具栏
			
			$("#paper").mousemove(function(e) {
				x = e.pageX;
				y = e.pageY - 41;
               $("#x").val(x);
               $("#y").val(y);
				
				if(newPath) {
					newLine.attr("path", newPath + "L" + x + "," + y);
				}
			}).click(function() {
				if(newPath) {
					newPath += "L" + x + "," + y;
					newLine.attr("path", newPath);
					opt.points.push({"cx":x, "cy":y});
				}
			}).css("cursor","crosshair");
			
			//打开taskhover函数
			context.linkHover();
			//LineTemp对象获得焦点事的事件
			ts.isMe(true);
			//设置连线状态开启
			isDraw = true;
		});
		
		/**LineTemp对象获得焦点事的事件
		 */
		this.isMe = function(me) {
			if(me) {
				if(context.isMe) {
					context.isMe.isMe(false);
				}
				//注册当前操作的line对象到context
				context.isMe = this;
			}else {
				context.isMe = null;
			}
		};
		
		/**添加task感应圈至此线条
		 */
		this.addPoint = function(tid, point) {
			if(!newPath) { //添加第一个点时
				opt.tid = tid;
				opt.points.push(point.attr(['cx', 'cy']));
				
				newPath = "M"+point.attr("cx")+","+point.attr("cy");
				newLine.attr("path", newPath);
				
				context.linkUnhover(tid);
			}else { //添加最后一个点
				opt.growTo = tid;
				opt.points.push(point.attr(['cx', 'cy']));
				new Line(opt);
				
				ts.reset();
			}
		};
		
		/**还原状态
		 */
		this.reset = function() {
			//设置连线状态关闭
			isDraw = false;
			newPath = null;
			newLine.attr("path", "");
			
			opt.points.splice(0, opt.points.length);
			$("#cloth").hide();
			
			context.linkUnhover();
			$('#paper').unbind().css("cursor","default"); //移除所有事件
		};
	};
	//------------------JQuery注入-------------------------line模板----end----------------------------------------------
	
	//------------------JQuery注入-------------------------全局事件----begin----------------------------------------------
	function toolInit() {
		/**
		 * 删除对象
		 * 包括删除TaskArea对象和Line对象及取消正在连线中的LineTemp对象
		 */
		$(document).keydown(function(e){
			if(e.keyCode == 46) {
				//判断删除的是taskArea还是line
				if(context.isMe) {
					if(context.isMe.lid) { //线条
						context.isMe.destroy();
					}else { //taskArea
						context.remove(context.isMe.tid);
					}
				}
			}else if(e.keyCode == 27) {
				context.lt.reset();
			};
		});
		
		/**
		 * 数据栏拖拽
		 */
		$("#data_top").mousedown(function(e) {
			var pos_x = Number($("#data").css("left").replace("px", "")) - e.pageX;
			var pos_y = Number($("#data").css("top").replace("px", "")) - e.pageY;
			$("#wf_body").mousemove(function(s) {
				$("#data").css({
					"top": pos_y + s.pageY,
					"left": pos_x + s.pageX
				});
			});
		}).mouseup(function() {
			$("#wf_body").unbind();
		});
		
		/**
		 * 数据栏数据修改监听事件
		 */
		$("#hm_text").change(function() {
			if(context.isMe) {
				context.isMe.text.attr("text", $(this).val());
			}
		});
		$("#hm_step").change(function() {
			if(context.isMe) {
				context.isMe.step = $(this).val();
			}
		});
		$("#hm_page").change(function() {
			if(context.isMe) {
				context.isMe.page = $(this).val();
			}
		});
		$("#hm_role").change(function() {
			if(context.isMe) {
				if(context.isMe.flag == 1) {
					context.appRole = $(this).val();
				}
				context.isMe.appRole = $(this).val();
			}
		});
		$("#hm_exeCid").change(function() {
			if(context.isMe) {
				context.isMe.exeCid = $(this).val();
			}
		});
		
		/**
		 * 文档监听事件 隐藏数据栏
		 */
		$(document).mousedown(function(e) {
			var t = e.target;
			while(t){
        		if(t.id == "paper" || t.id == "data") {
                	return;
        		}
        		t = t.parentNode;
   			}
			$("#data").hide();
			if(context.isMe) {
				context.isMe.isMe(false);
			}
        });
	};
	//------------------JQuery注入-------------------------全局事件----end----------------------------------------------
	//------------------JQuery注入-------------------------设计器面板功能按钮事件----begin----------------------------------------------
	function btnEvent() {
		/**
		 * 导入已有流程
		 */
		$("#wf_im_exist").click(function() {
			$(".isolate_div").show();//打开隔离层
			$("#import_sc").empty();//清空前纪录
			
			regist_wf = null;
			$.ajax({
				url: "folder.action?folder=all",
				type: "GET",
				dataType: "json",
				cache: false,
				error: function() {
					alert("数据请求失败！");
				},
				success: function(o) {
					var temp = "<ul>";
					for(var i=0; i < o.length; i++) {
						temp += "<li>&diams;"+o[i].name+"<ul class='ul_blue'>";
						for(var j=0; j < o[i].graphs.length; j++) {
							temp += "<li>"+o[i].graphs[j].name+"<input type='hidden' value='"+o[i].graphs[j].graphId+"'/></li>";
						}
						temp += "</ul></li>";
					}
					$("#import_sc").append(temp+"</ul>");
					$(".ul_blue li").click(function() {
						if(regist_wf != null) {
							regist_wf.css("color","black");
						}
						regist_wf = $(this).css("color","red");
					});
				}
			});
			//展开窗口
			$("#submit_panel").hide();
			$("#import_panel").show();
		});
		//确定导入
		$("#import_submit").click(function() {
			if(regist_wf == null) {
				alert("请选择一个流程！");
				return;
			}
			$.ajax({
				url: "import.action?graphId="+regist_wf.find(":input").val(),
				type: "GET",
				dataType: "json",
				cache: false,
				error: function() {
					alert("数据请求失败！");
				},
				success: function(o) {
					context.reset();//重置panel
					context.initDate(o);
				}
			});
			
			$("#import_panel").hide();//关闭窗口
			$(".isolate_div").hide();//关闭隔离层
		});
		//取消导入
		$("#import_canel").click(function() {
			$("#import_panel").hide();//关闭窗口
			$(".isolate_div").hide();//关闭隔离层
		});
		
		/**
		 * 发布流程
		 */
		$("#wf_im_publish").click(function() {
			$(".isolate_div").show();//打开隔离层
			$("#wf_publish_pkg").empty();//清空前纪录
			$("#package_name").val("");//清空文件夹
			
			isNew = true;//是否更新流程
			
			regist_wf = null;
			//加载文件夹信息
			$.ajax({
				url: "folder.action",
				type: "GET",
				dataType: "json",
				cache: false,
				error: function() {
					alert("数据请求失败！");
				},
				success: function(o) {
					var temp = "";
					for(var i=0; i < o.length; i++) {
						if(context.folderId == o[i].folderId) { //更新判断
							temp += "<div>&diams;<span class='wf_package' style='color:red;'><span>"+o[i].name+"</span><input type='hidden' value='"+o[i].folderId+"'/></span></div>";
							isNew = false;
							$("#package_name").val(o[i].name);
						}else {
							temp += "<div>&diams;<span class='wf_package'><span>"+o[i].name+"</span><input type='hidden' value='"+o[i].folderId+"'/></span></div>";
						}
					}
					$("#wf_publish_pkg").append(temp);
					
					if(isNew) {
						$(".wf_package").click(function() {
							if(regist_wf != null) {
								regist_wf.css("color","black");
							}
							regist_wf = $(this).css("color","red");
							
							$("#package_name").val(regist_wf.find("span").html());
						});
					}else {
						$("#wf_name").val(context.name);
						$("#java_path").val(context.proClass);
					}
				}
			});
			//打开面板
			$("#import_panel").hide();
			$("#submit_panel").show();
		});
		//确定发布
		$("#wf_publist_btn").click(function() {
			if(isNew) { //新建
				if(regist_wf == null) {
					alert("请选择一个流程文件夹！");
					return;
				}
				//数据封装
				context.setData({folderId:regist_wf.find(":input").val(), name:$("#wf_name").val(), proClass:$("#java_path").val()});
			}else { //更新
				//数据封装
				context.setData({name:$("#wf_name").val(), proClass:$("#java_path").val()});
			}
			
			$.ajax({
				url: "publish.action",
				type: "POST",
				dataType: "text",
				cache: false,
				data: {
					graph: context.fmtGraph(),
					tasks: context.fmtTask(),
					lines: context.fmtLine()
				},
				error: function() {
					alert("数据保存失败，请检查数据！");
				},
				success: function(o) {
					alert(o);
				}
			});
			
			$("#submit_panel").hide();//关闭窗口
			$(".isolate_div").hide();//关闭隔离层
		});
		//取消流程发布：关闭流程发布面板
		$("#submit_canel").click(function() {
			$("#submit_panel").hide();//关闭窗口
			$(".isolate_div").hide();//关闭隔离层
		});
		
		/**
	     * 保存流程数据并下载xml文件
	     */
	    $("#wf_im_save").click(function() {
	    	alert("开发中...");
	    });
	    
	    /**
	     * 新建流程
	     * @param {Object} e
	     */
	    $("#wf_new").click(function() {
	    	alert("开发中...");
	    });
	    
	    /**
	     * 流程图美化器
	     * @param {Object} e
	     */
	    $("#wf_im_betiy").click(function() {
	    	alert("开发中...");
	    });
	    
	    /**
	     * 网格开关
	     */
	    $(".wf_switch_cloth").click(function() {
	    	if($(".wf_switch_zone").css("margin-left") == "0px") { //关闭
		    	$(".wf_switch_zone").animate({
					"margin-left":'-62px'
			    }, 500, function() {
			    	$("#paper").removeClass("wf_paper_bg");
			    });
	    	}else { //打开
		    	$(".wf_switch_zone").animate({
					"margin-left":'0'
			    }, 500, function() {
			    	$("#paper").addClass("wf_paper_bg");
			    });
	    	}
	    });
		//-------------------------------------------流程图测试----begin----------------------------------------------
		$("#wf_test").click(function () {
			$("#sb_data").val(context.fmtTask());
			//$("#sb_data").val(context.fmtLine());
			//$("#sb_data").val(context.fmtGraph());
		});
		//-------------------------------------------流程图测试----end----------------------------------------------
	};
	//------------------JQuery注入-------------------------设计器面板功能按钮事件----end----------------------------------------------
	//------------------阻止事件冒泡-------------------------全局事件----begin----------------------------------------------
	/**
	 * 阻止事件冒泡
	 */
	function stop(e) {
		var s = e || window.event;
		s.stopPropagation ? s.stopPropagation() : (s.cancelBubble=true);
	}
	//------------------阻止事件冒泡-------------------------全局事件----end----------------------------------------------
	//------------------JQuery注入-------------------------DataLink----begin----------------------------------------------
	function dataLink(o) {
		$("#hm_text").val(o.text);
		$("#hm_step").val(o.step);
		$("#hm_page").val(o.page);
		$("#hm_role").val(o.appRole);
		$("#hm_exeCid").val(o.exeCid);
		$("#data").show();
	};
	//------------------JQuery注入-------------------------DataLink----end----------------------------------------------
})(window.WorkFlow);